<?php
namespace App\Repository\Db;

use App\Exceptions\ValidateException;
use App\Model\MemberIntegral;
use App\Model\MemberRecharge;
use App\Model\Shopping;
use App\Repository\Contracts\GoodsInterface;
use App\Repository\Contracts\MemberIntegralInterface;
use App\Repository\Contracts\MemberRechargeInterface;
use App\Repository\Contracts\RefundShoppingInterface;
use App\Repository\Contracts\ShoppingInterface;
use App\Repository\Contracts\ShoppingJavaInterface;
use Illuminate\Support\Facades\DB;

/**
 * @Author:: HuangYin
 * @DateTime: 2017-02-22 14:33
 *
 * @Description:
 */
class RefundShoppingRepository extends Repository implements RefundShoppingInterface
{
    protected $rules = [
        'created' => [
            'admin_id' => 'required|exists:admin,uid',
            'store_id' => 'required',
            'member_id' => 'sometimes|exists:member,uid',
            'trade_no' => 'required',
            'amount' => 'required'
        ]
    ];

    protected $messages = [
        'admin_id.required' => "管理员不能为空",
        'admin_id.exists' => "管理员 ID 不存在",
        'store_id.required' => "门店 ID 不能为空",
        'member_id.exists' => "会员 ID 不存在",
        'trade_no.required' => "购物号不能为空",
        'amount.required' => "退款金额不能为空"
    ];

    protected function modelName()
    {
        return 'App\Model\RefundShopping';
    }

    public function lists($limit, $page, $map = [])
    {
        $query = $this->searchMap($map);
        $total = $query->count();
        $data = $query->orderBy('uid', 'desc')->with('member')->simplePaginate($limit, ['*'], 'page', $page);
        $list = [];
        foreach ($data as $key => $val) {
            $list[$key] = $val;
            $list[$key]['username'] = $val->member->real_name;
        }

        return $this->simplePaginate('list', $list, $total, ceil($total / $limit), $page);
    }

    public function detail($map = [], $isAll = false)
    {
        if ($isAll) {
            return $this->searchMap($map)->with('detail')->get()->toArray();
        }
        $result = [];
        $data = $this->searchMap($map)->with('detail')->first();
        if ($data) {
            $result = $data->toArray();
            $result['detail'] = $data->detail->toArray();
        }

        return $result;
    }

    public function created(array $data)
    {
        $this->validate($data, 'created');
        try {
            // 开启事物
            DB::beginTransaction();
            $shopping = $this->container->make(ShoppingInterface::class)->detail([
                ['field' => 'out_trade_no', 'value' => $data['trade_no'], 'operation' => '=']
            ]);
            if (empty($shopping)) {
                throw new ValidateException('购物单不存在');
            }
            $goodsIds = array_column($shopping['detail'], 'goods_id');
            $refundIds = array_column($data['source'], 'goods_id');
            $intersect = array_intersect($refundIds, $goodsIds);
            if (!empty(array_diff($refundIds, $intersect))) {
                throw new ValidateException('非法参数');
            }
            $refunds = $this->getRefunds($data['amount'], $shopping['card_amount']);
            $refundData = [
                'uid' => $shopping['uid'], 'out_trade_no' => $shopping['out_trade_no'], 'admin_id' => $data['admin_id'],
                'auth_code' => $shopping['auth_code'], 'trade_no' => $shopping['trade_no'],
                'card_amount' => $refunds['cardAmount'], 'amount' => $refunds['amount'],
                'pay_type' => $shopping['pay_type'], 'pay_status' => $shopping['pay_status'],
                'status' => $shopping['status']
            ];
            $refundId = $this->save($refundData);
            $detail = $this->container->make(ShoppingInterface::class)->listBy($shopping['id'], $refundIds);
            $refundDetailData = $inventory = [];
            foreach ($data['source'] as $val) {
                $refundDetailData[] = [
                    'refund_id' => $refundId, 'goods_id' => $detail[$val['goods_id']]['goods_id'],
                    'zh_name' => $detail[$val['goods_id']]['zh_name'], 'en_name' => $detail[$val['goods_id']]['en_name'],
                    'price' => $detail[$val['goods_id']]['price'], 'counts' => $val['counts']
                ];
                $inventory[] = ['goods_id' => $val['goods_id'], 'counts' => $val['counts']];
            }
            if (!DB::table('refund_shopping_detail')->insert($refundDetailData)) {
                throw new ValidateException('操作失败');
            }
            $memberId = $shopping['uid'];
            // 会员
            if ($memberId) {
                // 会员卡消费变更
                if ($refunds['cardAmount'] > 0) {
                    $recharge = [
                        'uid' => $memberId, 'store_id' => $data['store_id'], 'admin_id' => $data['admin_id'],
                        'type' => MemberRecharge::REFUND, 'money' => round($refunds['cardAmount'], 2)
                    ];
                    $this->container->make(MemberRechargeInterface::class)->created($recharge);
                }
                // 积分变更
                $integral = ['uid' => $memberId, 'store_id' => $data['store_id'],
                    'type' => MemberIntegral::REFUND, 'integral' => $data['amount']
                ];
                $this->container->make(MemberIntegralInterface::class)->created($integral);
            }
            // 库存处理 -
            $this->container->make(GoodsInterface::class)->updateInventory($inventory);
            // 关闭事务
            DB::commit();
            return $shopping['out_trade_no'];
        } catch (ValidateException $e) {
            throw new ValidateException($e->getMessage());
        }
    }

    public function sync($storeId)
    {
        if (env('DIRECT_SALE') && env('JAVA_NETWORK')) {
            $data = $this->model->where('status', '=', 2)->with('detail')->get();
            $ids = [];
            foreach ($data as $val) {
                $ids[] = $val->id;
                $this->container->make(ShoppingJavaInterface::class)->syncRefund($storeId, $val->toArray());
                sleep(2);
            }
            $this->model->whereIn('id', $ids)->update(['status' => 3]);
        }

        return true;
    }

    public function syncAmount($storeId)
    {
        if (env('DIRECT_SALE') && env('JAVA_NETWORK')) {
            $data = $this->model->where('status', '=', 1)->get();
            $ids = [];
            foreach ($data as $val) {
                $ids[] = $val->id;
                $this->container->make(ShoppingJavaInterface::class)->syncRefundAmount($storeId, $val->toArray());
                sleep(2);
            }
            $this->model->whereIn('id', $ids)->update(['status' => 2]);
        }

        return true;
    }

    /**
     * 支持退款一次
     *
     * @param $refundAmount [退款金额]
     * @param $cardAmount [会员卡消费金额]
     * @return array
     */
    protected function getRefunds($refundAmount, $cardAmount)
    {
        if (strval($cardAmount * 100) > strval($refundAmount * 100)) {
            $result['cardAmount'] = $refundAmount;
            $result['amount'] = 0;
        } else {
            $result['cardAmount'] = $cardAmount;
            $result['amount'] = $refundAmount - $cardAmount;
        }

        return $result;
    }
}